package com.zoweunion.mechanic.controller.api;


import ch.qos.logback.core.joran.spi.XMLUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.github.wxpay.sdk.WXPayUtil;
import com.zoweunion.mechanic.config.AlipayConfig;
import com.zoweunion.mechanic.config.wx.WXPayConfig;
import com.zoweunion.mechanic.controller.BaseController;
import com.zoweunion.mechanic.dao.PromotionCouponDao;
import com.zoweunion.mechanic.dao.UserCouponDao;
import com.zoweunion.mechanic.entity.PromotionCouponEntity;
import com.zoweunion.mechanic.entity.UserCouponEntity;
import com.zoweunion.mechanic.model.ResponseBean;
import com.zoweunion.mechanic.model.User;
import com.zoweunion.mechanic.util.Orgin;
import com.zoweunion.mechanic.util.constants.Constants;
import com.zoweunion.mechanic.util.MyException;
import com.zoweunion.mechanic.util.wx.WXPayService;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/onlinePay")
@SuppressWarnings("unchecked")
public class AppPayController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(AppPayController.class);

    @Autowired
    private WXPayConfig wxPayConfig;
    @Autowired
    private WXPayService wxPayService;
    @Autowired
    private PromotionCouponDao promotionCouponDao;
    @Autowired
    private UserCouponDao userCouponDao;


    /**
     * 支付宝支付调用支付宝支付接口
     */
    @PostMapping("alipay")
    public Object alipayIumpSum(@RequestBody String str, HttpServletResponse response,HttpServletRequest servletRequest) throws Exception {

        Map<String, Object> reqMap = JSONObject.parseObject(str, Map.class);
        User currentUser = getCurrentUser(servletRequest);
        if(reqMap.get("payType")!=null&&Integer.parseInt(reqMap.get("payType").toString())==Constants.ORDER_WORK){
            if(currentUser.getR_id().equals("1")){
                reqMap.put("u_s_id", currentUser.getId());
            }
            reqMap.put("s_id", currentUser.getS_id());
            reqMap.put("r_id", currentUser.getR_id());
            reqMap.put("id", currentUser.getId());
            reqMap.put("user_name", currentUser.getUser_name());
            reqMap.put("remaining_sum", currentUser.getRemaining_sum());
            reqMap.put("credit_limit", currentUser.getCredit_limit());
        }
        //订单金额(必填)
        String payMoney = reqMap.get("payMoney").toString();
        //订单名称(必填)
        String orderId = reqMap.get("orderId").toString();
        //商品描述(可空)
        String orderDes = reqMap.get("orderDes").toString();
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。

        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

        model.setBody("工单支付");
        model.setSubject(orderDes);
        model.setOutTradeNo(orderId);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(payMoney);
        model.setProductCode("QUICK_MSECURITY_PAY");
        String passBack = JSONObject.toJSONString(reqMap);
        model.setPassbackParams(passBack);
        request.setBizModel(model);
        request.setNotifyUrl("https://disapi.zoweunion.com/mechanic/onlinePay/notify");
        //request.setNotifyUrl("https://zyhapi.mynatapp.cc/mechanic/onlinePay/notify");

        String orderString = "";
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response1 = alipayClient.sdkExecute(request);
            orderString = response1.getBody();//就是orderString 可以直接给客户端请求，无需再做处理。

        } catch (AlipayApiException e) {

            e.printStackTrace();
        }
        wxPayService.insertAliPay(reqMap);

        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", orderString);
    }

    /**
     * 微信支付接口
     *
     * @throws Exception
     */
    @RequestMapping(value = "/wechatNotifyPay")
    public void testPay(HttpServletRequest request, HttpServletResponse response) throws Exception {
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        Map xmlToMap = com.zoweunion.mechanic.util.XMLUtil.xmlToMap(result);
        boolean payStatus = wxPayService.selectPayStatus(xmlToMap);
        // 支付成功，商户处理后同步返回给微信参数
        PrintWriter writer = response.getWriter();
        if (payStatus) {
            // 通知微信已经收到消息
            String noticeStr = wxPayService.setXML("SUCCESS", "");
            writer.write(noticeStr);
            writer.flush();
        }else {
            String noticeStr = wxPayService.setXML("FAIL", "");
            writer.write(noticeStr);
            writer.flush();
        }
    }


    @PostMapping("/notify")
    public String aliPayCertNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String, String> returnMap = new HashMap<>();
        Set<Map.Entry<String, String[]>> entries = request.getParameterMap().entrySet();
        // 遍历
        for (Map.Entry<String, String[]> entry : entries) {
            String key = entry.getKey();
            StringBuffer value = new StringBuffer("");
            String[] val = entry.getValue();
            if (null != val && val.length > 0) {
                for (String v : val) {
                    value.append(v);
                }
            }
            returnMap.put(key, value.toString());
        }
        return wxPayService.selectPayStatusAli(returnMap);
    }

    @PostMapping("/wechatPay")
    public ResponseBean weiXinPay(@RequestBody String str,HttpServletRequest request) throws Exception {
        logBefore(logger, "微信支付接口");
        Map<String, Object> reqMap = JSONObject.parseObject(str, Map.class);
        Integer payType=0;
        double paymentAmount=0;
        double price=0;
        long couponId=0l;
        User currentUser = getCurrentUser(request);
        String orderId = reqMap.get("orderId").toString();
        if ( reqMap.containsKey("payMoney")){
            price = Double.parseDouble(reqMap.get("payMoney").toString());
        }
        if (reqMap.containsKey("paymentAmount")){
            paymentAmount = Double.parseDouble(reqMap.get("paymentAmount").toString());
        }
        if (reqMap.containsKey("couponId")){
            couponId = Orgin.getLongValue(reqMap, "couponId");
        }

        if (reqMap.containsKey("payType")){
            payType = Integer.valueOf(reqMap.get("payType").toString());
        }
        if (couponId!=0){
            UserCouponEntity entity = userCouponDao.selectById(couponId);
            PromotionCouponEntity couponEntity =
                    promotionCouponDao.selectById(entity.getCouponId());
            if (couponEntity.getUseScope()!=payType){
                throw new MyException(Constants.CODE_HANDEL_FAILED, "该类别不可使用");
            }
        }
        String body = reqMap.get("payBody").toString();
        String productId = reqMap.get("product_id").toString();
        Map<String, String> responseMap;
        try {
            responseMap = wxPayService.sendPayment(body, orderId, price, productId,payType,currentUser,paymentAmount,couponId);
            if (responseMap.containsKey("err_code_des")){
                return new ResponseBean(Constants.CODE_HANDEL_FAILED,responseMap.get("err_code_des").toString(),responseMap.get("err_code_des").toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(Constants.CODE_HANDEL_FAILED, "支付失败");
        }
        // 判断是否出现错误信息
        if (wxPayService.isError(responseMap)) {
            logger.error(wxPayService.errorMsg(responseMap));
            throw new MyException(Constants.CODE_HANDEL_FAILED, "支付失败");
        }

        Map<String, Object> resMap = new HashMap<>(5);

        Map<String, String> signMap = new HashMap<>(16);
        signMap.put("appid", responseMap.get("appid"));
        signMap.put("partnerid", wxPayConfig.getMchID());
        signMap.put("noncestr", responseMap.get("nonce_str"));
        signMap.put("prepayid", responseMap.get("prepay_id"));
        signMap.put("package", "Sign=WXPay");
        signMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));


        String sign = WXPayUtil.generateSignature(signMap, wxPayConfig.getKey());
        responseMap.put("sign", sign);
        resMap.put("data", responseMap);

        resMap.put("timestamp", System.currentTimeMillis() / 1000);

        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", resMap);
    }
}
